package com.tjetc.aop;

import com.tjetc.annotion.Log;
import com.tjetc.mapper.LogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect //切面类 定义了通知和切点的关系
public class LogAspect {

    @Resource
    private LogMapper logMapper;

    @Pointcut("@annotation(com.tjetc.annotion.Log)")
    private void pointCut(){

    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        // TODO 获取用户名,需要通过解析session或token获取
        com.tjetc.entity.Log log = new com.tjetc.entity.Log();
        // 获取被增强的方法对象
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        // 获取被增强的方法对象
        Method method = methodSignature.getMethod();
        // 从方法中解析注解
        if (method != null){
            Log logAnnotation = method.getAnnotation(Log.class);
            System.out.println("模块名称:" + logAnnotation.model());
            log.setModel(logAnnotation.model());
            System.out.println("操作名称:" + logAnnotation.action());
            log.setAction(logAnnotation.action());
        }
        // 方法名称
        String name = method.getName();
        log.setMethodName(name);
        System.out.println("方法名称 = " + name);

        // 通过工具类获取Request对象
        RequestAttributes reqa = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) reqa;
        HttpServletRequest request = sra.getRequest();
        // 访问的url
        String url = request.getRequestURI().toString();
        log.setVisitUrl(url);
        System.out.println("访问的url = " + url);
        // 请求方式
        String methodName = request.getMethod();
        log.setVisitMethod(methodName);
        System.out.println("请求方式 = " + methodName);
        // 登录Ip
        String ipAddr = getIpAddr(request);
        log.setComputerIp(ipAddr);
        System.out.println("电脑ip地址 = " + ipAddr);
        // 操作时间
        log.setDate(new Date());
        // TODO 保存到数据库的操作
        logMapper.insert(log);

        return joinPoint.proceed();
    }

    public String getIpAddr(HttpServletRequest request){
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return ipAddress;
    }
}
